package org.gap.jseed.injection.annotation;

import static java.lang.String.format;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import org.gap.jseed.Injector;
import org.gap.jseed.injection.ClassWriter;
import org.gap.jseed.reflect.ClassAnnotationIterator;
import org.gap.jseed.reflect.MethodIterator;

public class EnvironmentInjectionBuilder implements Injector {
	@Override
	public void inject(ClassWriter javaWriter, Class<?> javaClass) {
		if (Modifier.isAbstract(javaClass.getModifiers()) && hasEnvironmentAnnotation(javaClass)) {
			MethodIterator iterator = new MethodIterator(javaClass);

			for (Method each : iterator) {
				injectMethods(javaWriter, each);
			}
		}
	}

	private <T> boolean hasEnvironmentAnnotation(Class<T> javaClass) {
		ClassAnnotationIterator iterator = new ClassAnnotationIterator(javaClass);
		for (Annotation each : iterator) {
			if (each.annotationType().equals(Environment.class)) {
				return true;
			}
		}
		return false;
	}

	private void injectMethods(ClassWriter javaWriter, Method method) {
		String property = method.getName().substring(3);
		javaWriter.addSetterMethod(property, method.getReturnType(), Inject.class);
		javaWriter.writeBody(method, format("{ return %s; }", property));
	}
}
